package com.zerui.manager.icc.conf;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dahuatech.hutool.http.ContentType;
import com.dahuatech.hutool.http.Method;
import com.dahuatech.icc.exception.ClientException;
import com.dahuatech.icc.oauth.http.IClient;
import com.dahuatech.icc.oauth.http.IccHttpHttpRequest;
import com.zerui.manager.icc.properties.ICCProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@AllArgsConstructor
@Slf4j
public class ICCUrlForwardFilter extends HttpFilter {

    private final PathMatcher pathMatcher = new AntPathMatcher();


    private final IClient iccClient;


    private final ICCProperties iccProperties;


    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        String servletPath = req.getServletPath();
        if (pathMatcher.match("/api/icc/**", servletPath)) {

            String contentType = req.getContentType();
            String method = req.getMethod();
            String url = iccProperties.getUrl() + servletPath.replace("/api/icc", "");


            try {
                IccHttpHttpRequest request = new IccHttpHttpRequest(url, Method.valueOf(method));

                if (contentType.startsWith(ContentType.JSON.toString())) {
                    ServletInputStream inputStream = req.getInputStream();
                    String body = IoUtil.readUtf8(inputStream);
                    request.setBody(body);
                    log.info(">>> {} {} application/json {}", method, url, body);
                } else if (ContentType.FORM_URLENCODED.toString().equals(contentType)) {
                    ServletInputStream inputStream = req.getInputStream();
                    JSONObject jsonObject = JSON.parseObject(inputStream);
                    request.setForm(jsonObject);
                    log.info(">>> {} {} application/x-www-form-urlencoded {}", method, url, jsonObject);
                } else {
                    log.info(">>> {} {} {}", method, url, contentType);
                }

                String response = iccClient.doAction(request);
                log.info("<<< {}", response);
                ServletOutputStream outputStream = res.getOutputStream();
                res.setContentType("application/json");
                IoUtil.write(outputStream, true, response.getBytes(StandardCharsets.UTF_8));
            } catch (ClientException e) {
                log.warn("转发Icc请求异常. method: {}, servletPath: {}, contentType: {}", method, servletPath, contentType, e);
                res.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value());
            }
        } else {
            super.doFilter(req, res, chain);
        }
    }
}
